import math
import re

import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.ticker import MultipleLocator, FuncFormatter
from pandas import DataFrame

import xutils


class weather:
    def __init__(self) -> None:

        self.stationID = 'CHM00057679'
        self.df_PRCP = DataFrame(columns=['datetime', 'year', 'month', 'day', 'dayIndex', 'value', 'color'])  # 降雨数据
        self.df_TAVG = DataFrame(columns=['datetime', 'year', 'month', 'day', 'dayIndex', 'value', 'color'])  # 平均气温数据
        # self.df_TMAX = DataFrame(columns=['datetime', 'year', 'month', 'day', 'dayIndex', 'value'])  # 最高气温数据
        # self.df_TMIN = DataFrame(columns=['datetime', 'year', 'month', 'day', 'dayIndex', 'value'])  # 最低气温数据
        self.tMax = 0
        self.tMaxTime = ''
        self.tMin = 0
        self.tMinTime = ''
        self.pMax = 0
        self.pMaxTime = ''
        
        self.clean_data()

    def clean_data(self):

        # 导入数据
        with open(self.stationID + '.dly', 'r') as f1:
            dataList = f1.readlines()

        # 降雨天数索引
        pdi = 0
        # 气温天数索引
        tdi = 0

        for _d in dataList:
            # print("_d:{}".format(_d))

            # 使用正则对字符串进行分割
            _res = re.split("\s+|s|S", _d)
            # print("_res:{}".format(_res))
            
            # 清除结果集中的空字符串
            _date_res = list(filter(lambda x: x != '', _res))
            # print("_date_res:{}".format(_date_res))

            # 结果数组中的第一位为索引
            _title = _date_res[0]
            # 获取年
            _year = _title.replace(self.stationID, '')[0:4]
            # 获取月
            _month = _title.replace(self.stationID, '')[4:6]
            # 获取数据类型
            _type = _title.replace(self.stationID, '')[6:]
            # print('loding ' + str(_year) + str(_month))

            # 结果集中的后续内容为日数据值
            for i in range(1, len(_date_res)):
                _datetime = str(_year) + '-' + str(_month) + '-' + str(i)

                # 降雨记录
                if _type == 'PRCP':
                    if _month == '01' and i == 1:
                        pdi = 1
                    else:
                        pdi += 1

                    # 降雨量为 value / 10
                    _value = float(_date_res[i]) / 10
                    # 记录历史降雨量最高日期
                    if _value > self.pMax:
                        self.pMax = _value
                        self.pMaxTime = _year + '/' + _month + '/' + str(i)

                    _color = '#FFFFFF'
                    if _value > 0:
                        # 设置数据颜色值
                        _color = xutils.color(tuple(xutils.hsv2rgb(int(_value * 0.75) + 180, 1, 1)))
                    elif _value != -999.9:
                        _color = '#FFFFFF'
                    _df = DataFrame({'datetime': [_datetime], 'year': [_year], 'month': [_month], 'day': [i], 'dayIndex': [pdi],
                                    'value': [_value], 'color': [_color]})
                    
                    # 将单行数据添加至总DF中
                    self.df_PRCP = self.df_PRCP.append(_df, ignore_index=True)

                # 平均气温记录
                elif _type == 'TAVG':
                    if _month == '01' and i == 1:
                        tdi = 1
                    else:
                        tdi += 1
                    # 温度为 value / 10
                    _value = str(_date_res[i]).find('T') == True and -9999 or float(_date_res[i]) / 10

                    _color = '#FFFFFF'
                    if _value != -999.9:
                        # 设置数据颜色值
                        _color = xutils.color(tuple(xutils.hsv2rgb(int(-7 * _value) + 240, 1, 1)))
                    
                    _df = DataFrame({
                        'datetime': [_datetime], 
                        'year': [_year], 
                        'month': [_month], 
                        'day': [i], 
                        'dayIndex': [tdi],
                        'value': [_value], 
                        'color': [_color]})
                    self.df_TAVG = self.df_TAVG.append(_df, ignore_index=True)

                # 最高气温记录
                elif _type == 'TMAX':
                    _value = str(_date_res[i]).find('T') == True and 0 or float(_date_res[i]) / 10
                    if _value > self.tMax and _value < 100:
                        self.tMax = _value
                        self.tMaxTime = _year + '/' + _month + '/' + str(i)

                # 最低气温记录
                elif _type == 'TMIN':
                    _value = str(_date_res[i]).find('T') == True and 0 or float(_date_res[i]) / 10
                    if _value < self.tMin and _value > -100:
                        self.tMin = _value
                        self.tMinTime = _year + '/' + _month + '/' + str(i)
            # 调试使用，避免数据加载时间过长
            # if len(self.df_PRCP) and len(self.df_TAVG) > 100:
            #     break

        self.df_PRCP = self.df_PRCP.set_index('datetime')
        self.df_TAVG = self.df_TAVG.set_index('datetime')

    def show_rainy_count(self):
        # 设置figure_size尺寸
        plt.rcParams['figure.figsize'] = (10.0, 6.0)
        # 设置 颜色 style
        plt.rcParams['image.cmap'] = 'gray'
        # 分辨率
        plt.rcParams['figure.dpi'] = 200
        # 图片像素
        plt.rcParams['savefig.dpi'] = 200
        # 设置 interpolation style
        plt.rcParams['image.interpolation'] = 'nearest'
        # 柱状图

        # 年连续降雨最长时间段统计
        # 提交给自定义统计函数进行计算
        # print("self.df_PRCP:", self.df_PRCP)
        df_stillRainyD = (self.df_PRCP[self.df_PRCP['value'] > 0]).groupby('year').apply(xutils.continue_count)
        df_stillRainyD = df_stillRainyD.set_index('year')

        plt.xlabel("Month")
        plt.ylabel("Year")
        plt.title("Continuous Rainy Count : 1951-2019")
        plt.barh(df_stillRainyD.index, df_stillRainyD['maxCount'], left=df_stillRainyD['maxDayIndex'],
                color=list(map(lambda v: xutils.color(tuple(xutils.hsv2rgb(int(6 * v) + 120, 1, 1))), 
                df_stillRainyD['maxCount'])),
                align='edge') #  绘制横向柱状图

        # 设置主刻度
        plt.xlim(0, 365)
        plt.gca().xaxis.set_major_locator(MultipleLocator(31))
        plt.gca().xaxis.set_major_formatter(FuncFormatter(xutils.month_formatter))
        plt.gca().yaxis.set_major_locator(MultipleLocator(5))
        plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda x, y: int(x + 1950)))
        # 设置次刻度
        plt.gca().xaxis.set_minor_locator(MultipleLocator(1))
        plt.gca().yaxis.set_minor_locator(MultipleLocator(1))

        # 打开网格
        plt.gca().xaxis.grid(True, which='major')  # x坐标轴的网格使用主刻度
        plt.gca().yaxis.grid(True, which='minor')  # y坐标轴的网格使用次刻度
        # if ISTEST == False:
        plt.savefig("./Continuous-Rainy-Count.png")  # 保存图片
        plt.show()

    def show_tavg(self):
        # TAVG
        plt.gca().xaxis.set_major_locator(MultipleLocator(31))
        plt.gca().xaxis.set_major_formatter(FuncFormatter(xutils.month_formatter))
        plt.gca().grid()  # 网格
        # plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')
        plt.scatter(
            self.df_TAVG['dayIndex'], 
            self.df_TAVG['value'], 
            s=80, 
            c=self.df_TAVG['color'], 
            marker='.', 
            alpha=0.05)
        
        plt.xlim(0, 365)
        plt.ylim(-30, 50)
        plt.gca().yaxis.set_major_locator(plt.MultipleLocator(10))
        plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda x, y: str(x) + 'C°'))

        plt.title('TAVG : 1951-2019')
        plt.xlabel("Month")
        plt.ylabel("Temperature C°")

        plt.savefig("./TAVG.png") # 保存图片

        plt.show()

    def show_tavg_bu(self):
        # TAVG补温度显示
        plt.scatter(
            self.df_TAVG['dayIndex'], 
            self.df_TAVG['year'], 
            s=20, 
            c=self.df_TAVG['color'], 
            marker='|', 
            alpha=1)  # 散点图绘制
        
        plt.xlabel("Month")
        plt.ylabel("Year")
        plt.title("Historical TAVG Show : 1951-2019")

        # 设置主刻度
        plt.xlim(0, 365)
        plt.gca().xaxis.set_major_locator(MultipleLocator(31))
        plt.gca().xaxis.set_major_formatter(FuncFormatter(xutils.month_formatter))
        plt.gca().yaxis.set_major_locator(MultipleLocator(5))
        plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda x, y: int(x + 1951)))
        # 设置次刻度
        plt.gca().xaxis.set_minor_locator(MultipleLocator(1))
        plt.gca().yaxis.set_minor_locator(MultipleLocator(1))

        # 打开网格
        plt.gca().xaxis.grid(True, which='major')  # x坐标轴的网格使用主刻度
        plt.gca().yaxis.grid(True, which='minor')  # y坐标轴的网格使用次刻度
        plt.savefig("./Historical TAVG Show.png")  # 保存图片
        plt.show()




if __name__ == "__main__":
    weather = weather()
    # weather.show_rainy_count()
    # weather.show_tavg()
    weather.show_tavg_bu()

